﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using Infragistics.Win.Misc;
using System.Globalization;

namespace AutoParkingManagement
{
    public partial class EntryExitContainer : Form
    {
        #region Private members
        private LaneEntry laneEntryLeft;
        private LaneEntry laneEntryRight;
        private LaneExit laneExitLeft;
        private LaneExit laneExitRight;
        private string _username;
        private string _systemErrMessage = String.Empty;
        
        /// <summary>
        /// Display system time
        /// </summary>
        private void DisplaySystemTime()
        {
            lblSystemTime.Text = DateTime.Now.ToString("HH:mm:ss   dd/MM/yyyy");            
        }

        /// <summary>
        /// Create lanes
        /// </summary>
        private void InitialzieLanes()
        {
            pnlSeperate.Dock = DockStyle.Fill;

            laneEntryLeft = new LaneEntry(true);
            pnlCenterLeft.ClientArea.Controls.Add(laneEntryLeft);
            laneEntryLeft.URLFrontCamera = AppConfig.IPCameraLeftFront;
            laneEntryLeft.URLRearCamera = AppConfig.IPCameraLeftRear;

            laneEntryRight = new LaneEntry(false);
            pnlCenterRight.ClientArea.Controls.Add(laneEntryRight);
            laneEntryRight.URLFrontCamera = AppConfig.IPCameraRightFront;
            laneEntryRight.URLRearCamera = AppConfig.IPCameraRightRear;

            laneExitLeft = new LaneExit(true);
            pnlCenterLeft.ClientArea.Controls.Add(laneExitLeft);
            laneExitLeft.URLFrontCamera = AppConfig.IPCameraLeftFront;
            laneExitLeft.URLRearCamera = AppConfig.IPCameraLeftRear;

            laneExitRight = new LaneExit(false);
            pnlCenterRight.ClientArea.Controls.Add(laneExitRight);
            laneExitRight.URLFrontCamera = AppConfig.IPCameraRightFront;
            laneExitRight.URLRearCamera = AppConfig.IPCameraRightRear;

            laneEntryLeft.Dock = DockStyle.Fill;
            laneEntryRight.Dock = DockStyle.Fill;            
        }

        /// <summary>
        /// Display lanes (left, right)
        /// </summary>
        /// <param name="isEntry">true: entry, false: exit</param>
        /// <param name="ctlEntry">lane entry</param>
        /// <param name="ctlExit">lane exit</param>
        /// <param name="pnlContainer">panel container of entry, exit</param>
        private void DisplayLane(bool isEntry, LaneEntry ctlEntry, LaneExit ctlExit, UltraPanel pnlContainer)
        {
            ctlEntry.Visible = isEntry;
            ctlExit.Visible = !isEntry;
            if (isEntry)
            {
                ctlEntry.StartCameras();
                ctlExit.StopCameras();
            }
            else
            {
                ctlExit.StartCameras();
                ctlEntry.StopCameras();
            }
            if (pnlContainer == pnlCenterLeft)
            {
                if (isEntry)
                {
                    pnlLeft.Appearance.ImageBackground = Properties.Resources.LeftIn;
                }
                else
                {
                    pnlLeft.Appearance.ImageBackground = Properties.Resources.LeftOut;
                }
            }
            else
            {
                if (isEntry)
                {
                    pnlRight.Appearance.ImageBackground = Properties.Resources.RightIn;
                }
                else
                {
                    pnlRight.Appearance.ImageBackground = Properties.Resources.RightOut;
                }
            }
        }

        private void ResetPlateNumber()
        {            
            txtPlateNumber.Enabled = false;            
        }
       

        private void CaptureImage(LaneEntry laneEntry, LaneExit laneExit)
        {
            string strPlateNumber;
            if (laneEntry.Visible) //Entry gate
            {
                strPlateNumber = laneEntry.CapturePlateNumber();
                lblPrice.Text = String.Empty;
                if (!String.IsNullOrEmpty(laneEntry.Message))
                {
                    //MessageBox.Show(laneEntry.Message,this.Text,MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
                    Common.ShowMessage(this.Text, laneEntry.Message);
                    return;
                }

                lblEntryTime.Text = laneEntry.EntryExit.EntryTime.ToString("HH:mm dd/MM");
                txtPlateNumber.Focus();
            }
            else //Exit gate
            {                
                laneExit.EntryExit = new EntryExit();
                strPlateNumber = laneExit.CapturePlateNumber();
                laneExit.EntryExit.PlateNumber = strPlateNumber;
                if (!String.IsNullOrEmpty(laneExit.Message))
                {
                    //MessageBox.Show(laneExit.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    Common.ShowMessage(this.Text, laneExit.Message);
                    return;
                }
                if (!laneExit.Saved)
                {
                    lblEntryTime.Text = laneExit.EntryExit.EntryTime.ToString("HH:mm dd/MM");
                    lblPrice.Text = String.Empty;                
                }
                else
                {
                    lblEntryTime.Text = String.Empty;
                    lblPrice.Text = String.Empty;                
                }
            }
            /////////////////////////////////////////////            
            txtPlateNumber.Text = strPlateNumber;            
            txtPlateNumber.Enabled = true;
        }

        private void ResetLane(LaneEntry laneEntry, LaneExit laneExit)
        {
            laneEntry.ResetLane();
            laneExit.ResetLane();
        }

        private void SaveData(LaneEntry laneEntry, LaneExit laneExit)
        {
            txtPlateNumber.Text = txtPlateNumber.Text.Trim();
            if (laneEntry.Visible)
            {                
                if (laneEntry.Saved)
                {
                    //MessageBox.Show("Vui lòng chụp hình trước khi lưu thẻ.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, "Vui lòng chụp hình trước khi lưu thẻ.");
                    return;
                }                
                if (String.IsNullOrEmpty(txtPlateNumber.Text))
                {
                    //MessageBox.Show("Chưa nhận dạng được biển số.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, "Chưa nhận dạng được biển số.");
                    txtPlateNumber.Focus();
                    return;
                }
                laneEntry.EntryExit.PlateNumber = txtPlateNumber.Text;
                if (!laneEntry.SavePlateNumber())
                {
                    //MessageBox.Show(laneEntry.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, laneEntry.Message);
                    return;
                }
                else
                {
                    lblPrice.Text = String.Empty;
                    lblEntryTime.Text = laneEntry.EntryExit.EntryTime.ToString("HH:mm dd/MM");
                    if (laneEntry.EntryExit != null)
                    {
                        laneEntry.EntryExit = null;
                        GC.Collect();
                    }
                    //MessageBox.Show(laneEntry.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, laneEntry.Message);
                }
            }
            else
            {
                if (laneExit.Saved)
                {
                    //MessageBox.Show("Vui lòng chụp hình trước khi lưu thẻ.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, "Vui lòng chụp hình trước khi lưu thẻ.");
                    return;
                }

                if (String.IsNullOrEmpty(txtPlateNumber.Text))
                {
                    //MessageBox.Show("Chưa nhận dạng được biển số.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, "Chưa nhận dạng được biển số.");
                    txtPlateNumber.Focus();
                    return;
                }

                laneExit.EntryExit.PlateNumber = txtPlateNumber.Text;
                if (!laneExit.SavePlateNumber())
                {                    
                    //MessageBox.Show(laneExit.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    if(!String.IsNullOrEmpty(laneExit.Message))
                    {
                        Common.ShowMessage(this.Text, laneExit.Message);
                    }                    
                    if (laneExit.WrongPlateNumber)
                    {                        
                        txtPlateNumber.Focus();
                        txtPlateNumber.SelectAll();                        
                    }
                    return;
                }
                else
                {
                    if (laneExit.EntryExit.Price > 0)
                    {
                        lblPrice.Text = laneExit.EntryExit.Price.ToString("0,0", CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        lblPrice.Text = "0";
                    }
                    
                    lblEntryTime.Text = laneExit.EntryExit.EntryTime.ToString("HH:mm dd/MM");
                    if (laneExit.EntryExit != null)
                    {
                        laneExit.EntryExit = null;
                        GC.Collect();
                    }
                    Common.ShowMessage(this.Text, laneExit.Message);
                }
            }
            ResetPlateNumber();
        }

        #endregion

        #region Properties
        
        #endregion

        #region Public members
        public delegate void EntryExitClosedHandler();
        public event EntryExitClosedHandler EntryExitClosed;
        public delegate void SearchVehicleHandler();
        public event SearchVehicleHandler VehicleSearched; 
        #endregion

        #region Events

        private bool IsValidParkingFloor
        {
            get
            {
                string sql = @"SELECT Count(ParkingFloorID)
                              FROM [ParkingFloor]
                              WHERE [Name]=@Name";
                SqlParameter parm = new SqlParameter("@Name", SqlDbType.NVarChar, 50);
                parm.Value = AppConfig.ParkingFloor;
                object obj = SqlHelper.ExecuteScalar(CommandType.Text, sql, parm);
                return Convert.ToInt32(obj) > 0;
            }
        }

        private void EntryExitContainer_Load(object sender, EventArgs e)
        {            
            try
            {                
                Cursor.Current = Cursors.WaitCursor;
                if (!IsValidParkingFloor)
                {
                    Common.ShowMessage(this.Text, "Hầm xe không hợp lệ.");
                    this.Close();
                }

                if (WinApi.ScreenX < 1360)
                {
                    this.Width = 1280;
                    pnlLeft.Width = 30;
                    pnlRight.Width = 30;
                    pnlSeperate.Width = 10;
                }
                lblEntryTime.Text = String.Empty;
                lblPrice.Text = String.Empty;
                DisplaySystemTime();
                Taskbar.Hide();
                FormState.IsMaximized = false;
                FormState.Maximize(this);
                InitialzieLanes();
                //Load profile for current user
                DataRow row = Common.ReadProfile(_username);
                bool isLeftEntry = true;
                bool isRightEntry = true;
                if (row != null)
                {
                    isLeftEntry = row["LeftEntry"].ToString().Equals("True");
                    isRightEntry = row["RightEntry"].ToString().Equals("True");
                }
                DisplayLane(isLeftEntry, laneEntryLeft, laneExitLeft, pnlCenterLeft);
                DisplayLane(isRightEntry, laneEntryRight, laneExitRight, pnlCenterRight);
                ResetPlateNumber();                
                //Test();
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                Cursor.Current = Cursors.Default;                
            }
        }

        private void btnChangeLaneLeft_Click(object sender, EventArgs e)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                DisplayLane(!laneEntryLeft.Visible, laneEntryLeft, laneExitLeft, pnlCenterLeft);
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
            
        }

        private void btnChangeLaneRight_Click(object sender, EventArgs e)
        {            
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                DisplayLane(!laneEntryRight.Visible, laneEntryRight, laneExitRight, pnlCenterRight);
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void btnHideLeft_Click(object sender, EventArgs e)
        {            
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                pnlCenterLeft.Visible = !pnlCenterLeft.Visible;
                if (!pnlCenterLeft.Visible)
                {
                    pnlLeft.Appearance.ImageBackground = Properties.Resources.Left;
                }
                else
                {
                    if (laneEntryLeft.Visible)
                    {
                        pnlLeft.Appearance.ImageBackground = Properties.Resources.LeftIn;
                    }
                    else
                    {
                        pnlLeft.Appearance.ImageBackground = Properties.Resources.LeftOut;
                    }
                }
                ResetPlateNumber();
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void btnHideLaneRight_Click(object sender, EventArgs e)
        {            
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                pnlCenterRight.Visible = !pnlCenterRight.Visible;
                if (!pnlCenterRight.Visible)
                {
                    pnlRight.Appearance.ImageBackground = Properties.Resources.Right;
                }
                else
                {
                    if (laneEntryRight.Visible)
                    {
                        pnlRight.Appearance.ImageBackground = Properties.Resources.RightOut;
                    }
                    else
                    {
                        pnlRight.Appearance.ImageBackground = Properties.Resources.RightIn;
                    }
                }
                ResetPlateNumber();
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

        }

        private void PrintReport()
        {
            TransferWorking frmTransferWorking = new TransferWorking();
            frmTransferWorking.ShowDialog();
            this.Close();            
        }

        private void Test()
        {
            System.Threading.Thread.Sleep(5000);
            while (true)
            {
                EntryExitContainer_KeyUp(null, new KeyEventArgs(Keys.F1));
                System.Threading.Thread.Sleep(1000);
                txtPlateNumber.Text = "999";
                System.Threading.Thread.Sleep(1000);
                EntryExitContainer_KeyUp(null, new KeyEventArgs(Keys.F2));
                System.Threading.Thread.Sleep(1000);
                EntryExitContainer_KeyUp(null, new KeyEventArgs(Keys.F9));
                System.Threading.Thread.Sleep(1000);
                txtPlateNumber.Text = "999";
                System.Threading.Thread.Sleep(1000);
                EntryExitContainer_KeyUp(null, new KeyEventArgs(Keys.F10));
                System.Threading.Thread.Sleep(1000);
            }            

        }

        private void EntryExitContainer_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                string strPlateNumber = String.Empty;
                if (e.KeyCode == Keys.F1)
                {
                    if (!laneEntryLeft.Visible && !laneExitLeft.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên trái chưa kích hoạt.");
                        return;
                    }
                    CaptureImage(laneEntryLeft, laneExitLeft);
                    ResetLane(laneEntryRight, laneExitRight);
                    //pnlCenterLeft.BorderStyle = Infragistics.Win.UIElementBorderStyle.Solid;
                    //pnlCenterRight.BorderStyle = Infragistics.Win.UIElementBorderStyle.None;
                }
                else if (e.KeyCode == Keys.F2)
                {
                    if (!laneEntryLeft.Visible && !laneExitLeft.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên trái chưa kích hoạt.");
                        return;
                    }
                    SaveData(laneEntryLeft, laneExitLeft);
                }
                else if (e.KeyCode == Keys.F3)
                {
                    if (!laneEntryLeft.Visible && !laneExitLeft.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên trái chưa kích hoạt.");
                        return;
                    }
                    DisplayLane(!laneEntryLeft.Visible, laneEntryLeft, laneExitLeft, pnlCenterLeft);
                    ResetPlateNumber();
                    if (laneEntryLeft.Visible)
                    {
                        laneEntryLeft.ResetLane();
                        //MessageBox.Show("Lane bên trái đã đảo thành lối vào");
                        Common.ShowMessage(this.Text, "Lane bên trái đã đảo thành lối vào");
                    }
                    else
                    {
                        laneExitLeft.ResetLane();
                        //MessageBox.Show("Lane bên trái đã đảo thành lối ra");
                        Common.ShowMessage(this.Text, "Lane bên trái đã đảo thành lối ra");
                    }

                }
                else if (e.KeyCode == Keys.F4)
                {
                    btnHideLeft_Click(null, null);
                }
                else if (e.KeyCode == Keys.F6)
                {
                    SearchCar frm = new SearchCar();
                    frm.ShowDialog();
                }
                else if (e.KeyCode == Keys.F9)
                {
                    if (!laneEntryRight.Visible && !laneExitRight.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên phải chưa kích hoạt.");
                        return;
                    }
                    CaptureImage(laneEntryRight, laneExitRight);
                    ResetLane(laneEntryLeft, laneExitLeft);

                }
                else if (e.KeyCode == Keys.F10)
                {
                    if (!laneEntryRight.Visible && !laneExitRight.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên phải chưa kích hoạt.");
                        return;
                    }
                    SaveData(laneEntryRight, laneExitRight);
                }
                else if (e.KeyCode == Keys.F11)
                {
                    if (!laneEntryRight.Visible && !laneExitRight.Visible)
                    {
                        Common.ShowMessage(this.Text, "Lane bên phải chưa kích hoạt.");
                        return;
                    }
                    DisplayLane(!laneEntryRight.Visible, laneEntryRight, laneExitRight, pnlCenterRight);
                    ResetPlateNumber();
                    if (laneEntryRight.Visible)
                    {
                        laneEntryRight.ResetLane();
                        //MessageBox.Show("Lane bên phải đã đảo thành lối vào");
                        Common.ShowMessage(this.Text, "Lane bên phải đã đảo thành lối vào");
                    }
                    else
                    {
                        laneExitRight.ResetLane();
                        //MessageBox.Show("Lane bên phải đã đảo thành lối ra");
                        Common.ShowMessage(this.Text, "Lane bên phải đã đảo thành lối ra");
                    }

                }
                else if (e.KeyCode == Keys.F12)
                {
                    btnHideLaneRight_Click(null, null);
                }
                else if (e.KeyCode == Keys.Escape)
                {
                    YesNoMessage frmMessage = new YesNoMessage(this.Text, "Bạn muốn xuất biên bản chuyển ca trước khi đóng màn hình?");
                    frmMessage.ShowDialog(this);
                    if (this.Tag.ToString() == DialogResult.No.ToString())
                    {
                        frmMessage = new YesNoMessage(this.Text, "Bạn chắc chắn đóng màn hình giữ xe?");
                        frmMessage.ShowDialog(this);
                        frmMessage.Dispose();
                        frmMessage = null;
                        GC.Collect();
                        if (this.Tag.ToString() == DialogResult.No.ToString())
                        {
                            return;
                        }
                        else
                        {
                            this.Close();
                        }
                        
                    }
                    else
                    {
                        PrintReport();
                    }
                }
                else if (e.KeyData == (Keys.Control | Keys.P)) 
                {
                    YesNoMessage frmMessage = new YesNoMessage(this.Text, "Bạn muốn xuất báo cáo chuyển ca phải không?");
                    frmMessage.ShowDialog(this);
                    frmMessage.Dispose();
                    frmMessage = null;
                    GC.Collect();
                    if (this.Tag.ToString() == DialogResult.Yes.ToString())
                    {
                        PrintReport();
                    }  
                }
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }

        }

        private void txtPlateNumber_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Tab)
            {
                txtPlateNumber.Text = txtPlateNumber.Text.Trim();                
                if(String.IsNullOrEmpty(txtPlateNumber.Text))
                {
                    //MessageBox.Show("Vui lòng nhập lại biển số xe",this.Text,MessageBoxButtons.OK,MessageBoxIcon.Warning);
                    Common.ShowMessage(this.Text, "Vui lòng nhập lại biển số xe");
                    return;
                }
                if (!laneEntryLeft.Saved)
                {
                    laneEntryLeft.EntryExit.PlateNumber = txtPlateNumber.Text;
                }
                if (!laneEntryRight.Saved)
                {
                    laneEntryRight.EntryExit.PlateNumber = txtPlateNumber.Text;
                }
                if (!laneExitLeft.Saved)
                {
                    laneExitLeft.EntryExit.PlateNumber = txtPlateNumber.Text;
                }
                if (!laneExitRight.Saved)
                {
                    laneExitRight.EntryExit.PlateNumber = txtPlateNumber.Text;
                }
                //SendKeys.Send("{TAB}");                             
            }
        }

        private void txtPlateNumber_EnabledChanged(object sender, EventArgs e)
        {
            if (txtPlateNumber.Enabled)
            {
                txtPlateNumber.BringToFront();
                txtPlateNumber.Focus();
            }
            else
            {
                txtPlateNumber.SendToBack();
                lblEntryTime.Text = String.Empty;
                lblPrice.Text = String.Empty;
            }
        }      

        private void tmrSystem_Tick(object sender, EventArgs e)
        {
            DisplaySystemTime();
        }

        private CloseReason _closeReason = CloseReason.None;

        private void EntryExitContainer_FormClosing(object sender, FormClosingEventArgs e)
        {
            _closeReason = e.CloseReason;
        }

        private void EntryExitContainer_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                laneEntryLeft.StopCameras();
                laneEntryRight.StopCameras();
                laneExitLeft.StopCameras();
                laneExitRight.StopCameras();
                Common.WriteProfile(_username, laneEntryLeft.Visible, laneEntryRight.Visible);
                Taskbar.Show();
                if (_closeReason == CloseReason.UserClosing)
                {
                    EntryExitClosed();
                }                
            }
            catch (Exception ex)
            {
                Common.ShowMessage(this.Text, _systemErrMessage);
            }
            finally
            {
                this.Dispose();
            }
        }

        
        #endregion

        #region Constructors
        public EntryExitContainer(string username, string fullName)
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            _username = username;
            lblLoginName.Text = fullName;
            _systemErrMessage = "Lỗi hệ thống..." + Environment.NewLine + "Vui lòng liên hệ quản trị hệ thống để được hỗ trợ";
        }
        #endregion
                
    }
}
